package hikari.managers;

import com.gooddies.wiring.annotations.Wire;
import com.gooddies.wiring.annotations.WiringComponent;
import hikari.gui.assets.AssetsTree;
import hikari.objects_data.Model3dData;
import hikari.persistence.file.Chunk;
import hikari.persistence.file.FileSection;
import hikari.persistence.file.HikariFile;
import hikari.utils.Utils;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author sad
 */
@WiringComponent(singleton = true, lazy = true)
public class AnimationSettingStore {

    @Wire
    private AssetsTree assetsTree;
    private Map<String, Object> assetsData = new HashMap<>();
    @Wire
    private Utils utils;

    private String getAnimationDescriptionFilePath(String path) {
        return utils.getFilePath(path) + utils.getFileNameWithoutExtension(path) + ".anim";
    }

    /**
     * Gets relative path
     */
    public Model3dData getDataForAnimationModel(String path) {
        String fullPath = assetsTree.getAbsoluteAssetPathFromRelativePath(path);
        Model3dData data = (Model3dData) assetsData.get(fullPath);
        if (data == null) {
            String animFilePath = getAnimationDescriptionFilePath(fullPath);
            if (!(new File(animFilePath).exists())) {
                data = new Model3dData();
            } else {
                data = readAnimFile(animFilePath);
            }
            assetsData.put(path, data);
        }
        return data;
    }

    private Model3dData readAnimFile(String path) {
        Model3dData data = new Model3dData();
        try {
            HikariFile file = new HikariFile(new File(path));
            file.openForReading();
            List<Chunk> sections = file.getAllSections();
            for (Chunk chunk : sections) {
                if (chunk.getName().equals("track")) {
                    FileSection animTracSection = file.readSection(chunk);
                    int startFrame = animTracSection.readInt(animTracSection.getChunk("startFrame"));
                    int endFrame = animTracSection.readInt(animTracSection.getChunk("endFrame"));
                    String trackName = animTracSection.readString(animTracSection.getChunk("trackName"));
                    float sequenceSpeed = animTracSection.readFloat(animTracSection.getChunk("speed"));
                    data.putAnimationTrack(trackName, startFrame, endFrame, sequenceSpeed);
                    animTracSection.close();
                }
            }
            file.close();
        } catch (IOException ex) {
            utils.logError(ex);
        }
        return data;
    }

    private void saveAnimFile(String path, Model3dData data) {
        try {
            HikariFile file = new HikariFile(new File(path));
            file.openForWriting();
            for (String track : data.getAnimationNames()) {
                Model3dData.AnimationTrackData trackData = data.getTrackData(track);
                FileSection trackSection = file.createNewSection("track");
                trackSection.writeString("trackName", track);
                trackSection.writeFloat("speed", trackData.getAnimationSpeed());
                trackSection.writeInt("startFrame", trackData.getStartFrame());
                trackSection.writeInt("endFrame", trackData.getEndFrame());
                trackSection.close();
            }
            file.close();
        } catch (IOException ex) {
            utils.logError(ex);
            utils.logError("Cannot save file " + path);
        }
    }

    public void putDataForAnimationModel(String path, Model3dData data) {
        String fullPath = assetsTree.getAbsoluteAssetPathFromRelativePath(path);
        String animFilePath = getAnimationDescriptionFilePath(fullPath);
        saveAnimFile(animFilePath, data);
        assetsData.put(path, data);
    }
}
